const { ccclass, property } = cc._decorator;
import LevelData from "./Model/LevelData"
@ccclass
export default class Game extends cc.Component {

    @property(cc.Node)
    gameMain: cc.Node = null;
    @property(cc.Node)
    tileBg: cc.Node = null;

    @property(cc.Node)
    fxBg: cc.Node = null;

    @property(cc.Prefab)
    tilePrf: cc.Prefab = null;


    /***target */
    @property(cc.Node)
    taegetList: cc.Node = null;

    @property(cc.Prefab)
    tarItem: cc.Prefab = null;

    @property(cc.Label)
    moveLB: cc.Label = null;

    @property(cc.Label)
    levelLB: cc.Label = null;

    /** */
    @property(cc.AudioClip)
    beginMusic: cc.AudioClip = null;
    @property(cc.AudioClip)
    backgroundMusic: cc.AudioClip = null;

    @property(cc.AudioClip)
    noMatch: cc.AudioClip = null;

    @property(cc.AudioClip)
    pop: cc.AudioClip = null;

    @property(cc.Prefab)
    fx: cc.Prefab[] = [];


    tiles = []
    maxNum = 5;

    isPass = false;//是否过关


    onLoad() {
        //播放背景音乐
        this.bgmId = cc.audioEngine.play(this.backgroundMusic, true, 0.5);

        // 方块背景层
        this.gameMain.width = cc.winSize.width - 30;
        this.gameMain.height = this.tileBg.width;
        this.gameMain.setPosition(15 - cc.winSize.width / 2, 0);

        this.tileBg.width = this.gameMain.width
        this.tileBg.height = this.gameMain.height

        cc.audioEngine.play(this.beginMusic);
        this.setLevel();
        this.initData();

        //cc.log(this.ttbg.children)

    }
    //
    setLevel() {
        LevelData.level = 1;
        LevelData.move = 30;
        LevelData.target = [
            { 'type': 1, 'num': 20 },
            { 'type': 2, 'num': 20 },
            { 'type': 4, 'num': 20 }
        ];

        this.moveLB.string = String(LevelData.move)
        this.levelLB.string = String(LevelData.level)
        LevelData.target.forEach(item => {
            var tagIem = cc.instantiate(this.tarItem)
            tagIem.getComponent("TarItem").init(item.type, item.num)

            tagIem.name = String(item.type)

            this.taegetList.addChild(tagIem)
        })
    }
    initData(level = 8) {
        // 初始化方块数组 9*11
        this.tiles = [
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null, null, null],
        ];
        // 生成初始方块
        for (var y = 0; y < this.tiles.length; y++) {
            for (var x = 0; x < this.tiles[0].length; x++) {
                var tile = cc.instantiate(this.tilePrf);
                tile.getComponent("Tile").game = this;
                tile.width = this.tileBg.width / this.tiles[0].length;
                tile.height = tile.width;
                var count = 0;
                var randomNum = 0;
                while (true) {
                    count++;
                    var arr = new Array();
                    var scanArr = new Array();
                    randomNum = Math.floor(Math.random() * 5) + 1;
                    tile.getComponent("Tile").set_type(randomNum)
                    tile.setPosition(tile.width * x + tile.width / 2, tile.height * y + tile.height / 2);
                    this.tiles[x][y] = tile;
                    this.scanAround(x, y, -1, -1, randomNum, arr, scanArr);
                    if (arr.length < level) {
                        break;
                    }
                }
                tile.getComponent("Tile").setArrPosition(x, y);
                this.tileBg.addChild(tile);
            }
        }
    }
    /*
     * 核心扫描逻辑
     * @param x 指定列
     * @param y 指定行
     * @param lastX 上次扫描的列
     * @param lastY 上次扫描的行
     * @param num 扫描要比对的数字
     * @param arr 记录数字相同且彼此相邻的数组
     * @param scanArr 记录扫描过的点的数组
     */
    scanAround(x, y, lastX, lastY, num, arr, scanArr) {
        if (this.tiles[x][y] == null) {
            return;
        }
        var isClear = false;
        if (scanArr == undefined) {
            scanArr = new Array();
        }
        // 扫描过的节点不再扫描
        if (scanArr.indexOf(x + "#" + y) == -1) {
            scanArr.push(x + "#" + y);
        } else {
            return;
        }
        // 扫描上
        if (y < this.tiles.length - 1 && (lastY != (y + 1) || lastX != x) && this.tiles[x][y + 1] != null) {
            var nextNum = parseInt(this.tiles[x][y + 1].getComponent("Tile").type);
            if (nextNum == num) {
                if (arr.indexOf(x + "#" + y) == -1) {
                    arr.push(x + "#" + y);
                }
                this.scanAround(x, y + 1, x, y, num, arr, scanArr);
                isClear = true;
            }
        }
        // 扫描下
        if (y > 0 && (lastY != (y - 1) || lastX != x) && this.tiles[x][y - 1] != null) {
            var nextNum = parseInt(this.tiles[x][y - 1].getComponent("Tile").type);
            if (nextNum == num) {
                if (arr.indexOf(x + "#" + y) == -1) {
                    arr.push(x + "#" + y);
                }
                this.scanAround(x, y - 1, x, y, num, arr, scanArr);
                isClear = true;
            }
        }
        // 扫描左
        if (x > 0 && (lastY != y || lastX != (x - 1)) && this.tiles[x - 1][y] != null) {
            var nextNum = parseInt(this.tiles[x - 1][y].getComponent("Tile").type);
            if (nextNum == num) {
                if (arr.indexOf(x + "#" + y) == -1) {
                    arr.push(x + "#" + y);
                }
                this.scanAround(x - 1, y, x, y, num, arr, scanArr);
                isClear = true;
            }
        }
        // 扫描右
        if (x < this.tiles[0].length - 1 && (lastY != y || lastX != (x + 1)) && this.tiles[x + 1][y] != null) {
            var nextNum = parseInt(this.tiles[x + 1][y].getComponent("Tile").type);
            if (nextNum == num) {
                if (arr.indexOf(x + "#" + y) == -1) {
                    arr.push(x + "#" + y);
                }
                this.scanAround(x + 1, y, x, y, num, arr, scanArr);
                isClear = true;
            }
        }
        // 四周都不通，但不是出发遍历点，并且数字相同，也加入到数组
        if (!isClear && (lastX != -1 && lastY != -1)) {
            var curNum = parseInt(this.tiles[x][y].getComponent("Tile").type)
            if (curNum == num) {
                if (arr.indexOf(x + "#" + y) == -1) {
                    arr.push(x + "#" + y);
                }
            }
        }
    }
    // 主要操作逻辑
    operateLogic(touchX, touchY, curNum, isFirstCall) {
        var arr = new Array();
        var scanArr = new Array();
        this.scanAround(touchX, touchY, -1, -1, curNum, arr, scanArr);
        if (arr.length >= 1) {
            //减步数
            LevelData.move--;
            this.moveLB.string = String(LevelData.move)
            //执行消除
            for (var index in arr) {
                var x = arr[index].split("#")[0];
                var y = arr[index].split("#")[1];
                if (x != touchX || y != touchY) { }
                var type = this.tiles[x][y].getComponent("Tile").type;

                //播放消除粒子
                var fx = cc.instantiate(this.fx[type - 1])
                fx.setPosition(this.tiles[x][y].getPosition());
                this.fxBg.addChild(fx)
                fx.getComponent("FxPlay").play()
                //检查方块是否是任务方块
                if (this.taegetList.getChildByName(String(type))) {
                    var tarItem: cc.Node = this.taegetList.getChildByName(String(type));
                    //移动到任务方块位置后消除
                    this.tiles[x][y].getComponent("Tile").destoryTileMoveToTarItem(fx, tarItem)

                } else {
                    //执行消除
                    this.tiles[x][y].getComponent("Tile").destoryTile(fx);
                }
                this.tiles[x][y] = null;

            }
            cc.audioEngine.play(this.pop, false, 0.5);
            this.scheduleOnce(function () {
                this.moveAllTileDown();
            }, 0.1);
        } else {
            cc.log("不能消除")
            cc.audioEngine.play(this.noMatch, false, 0.5);
        }
    }

    // 所有方块向下移动
    moveAllTileDown() {
        for (var y = 0; y < this.tiles.length; y++) {
            for (var x = 0; x < this.tiles[0].length; x++) {
                if (this.tiles[x][y] == null) {// 没有方块
                    for (var yy = y; yy < this.tiles.length; yy++) {
                        if (this.tiles[x][yy + 1] != null) {
                            this.tiles[x][y] = this.tiles[x][yy + 1]
                            this.tiles[x][yy + 1] = null;
                            this.tiles[x][y].getComponent("Tile").moveTo(x, y);
                            break;
                        }
                    }
                }
            }
        }
        //this.scheduleOnce(() => {
        //生成新的方块
        for (var y = 0; y < this.tiles.length; y++) {
            for (var x = 0; x < this.tiles[0].length; x++) {
                if (this.tiles[x][y] == null) {// 没有方块
                    var tile = cc.instantiate(this.tilePrf);
                    tile.getComponent("Tile").game = this;
                    tile.width = this.tileBg.width / this.tiles[0].length;
                    tile.height = tile.width;
                    var randomNum = 0;
                    randomNum = Math.floor(Math.random() * 5) + 1;
                    tile.getComponent("Tile").set_type(randomNum, false)
                    tile.getComponent("Tile").newTile(x, y)
                    this.tiles[x][y] = tile;
                    this.tileBg.addChild(tile);
                }
            }
        }



        //},0.3)

        /*this.schedule(() => {
            this.moveAllTileLeft();
        }, 0.01, this.tiles[0].length)*/

    }

    checkPass() {
        //判断任务是否完成
        this.isPass = true;
        LevelData.target.forEach(item => {
            var isOk = this.taegetList.getChildByName(String(item.type)).getComponent("TarItem").isOk
            if (!isOk) {
                this.isPass = false;
            }
        })
        if (this.isPass && LevelData.move >= 0) {
            cc.log("任务完成")
            cc.audioEngine.stop(this.bgmId)
        } else if (LevelData.move <= 0) {
            cc.log("过关失败,当前关卡游戏结束")
        }
    }

    //所有分块左移
    moveAllTileLeft() {
        for (var x = 0; x < this.tiles[0].length; x++) {
            var state = true;
            for (var y = 0; y < this.tiles.length; y++) {
                if (this.tiles[x][y] != null || x == this.tiles[0].length - 1) {
                    state = false;
                }
            }
            if (state) {
                for (var y = 0; y < this.tiles.length; y++) {
                    this.tiles[x][y] = this.tiles[x + 1][y]
                    this.tiles[x + 1][y] = null
                    if (this.tiles[x][y] != null) {
                        this.tiles[x][y].getComponent("Tile").moveTo(x, y, false);
                    }
                }
            }
        }
    }

    /*update() {
        
    }*/
}
